package Client.PokerClient.src;

import java.util.Timer;

import javax.swing.JOptionPane;
/**
 * Klasa obslugi gry.
 * @author Artur Smolibowski.
 */
public class GameController {
  /**
   * Referencja do glownego programu.
   */
  private Client client;
  /**
   * TimerThread odliczajacy czas na wymiane kart.
   */
  private TimerThread timerThread;
  /**
   * Timer odliczajacy czas na wymiane kart.
   */
  private Timer timer;
  /**
   * Tablica przechowujaca talie graczy.
   */
  private int[][][] PlayersDecks;
  /**
   * Tablica przechowuja karta wybrane przez gracza do wymiany.
   */
  private int[] ReplaceCards;
  /**
   * Tablica zawierajaca ID graczy.
   */
  private String[] PlayersID;
  /**
   * Zmienna przechowujaca aktualna liczbe graczy.
   */
  private int actualNumberOfPlayers;
  /**
   * Zmienna przechowujaca liczbe botow.
   */
  private int numberOfBot;
  /**
   * Zmienna przechowujaca maksymalna liczbe graczy.
   */
  private int maxPlayers;
  /**
   * Zmienna przechowujaca wartosc logiczna czy gracz jest hostem.
   */
  private boolean isPlayerHost=false;
  /**
   * Zmienna przechowujaca wartosc logiczna czy host gra.
   */
  private boolean isHostPlay=true;
  /**
   * Kostruktor klasy.
   * @param actualNumberOfPlayers Aktualna liczba graczy.
   * @param numberOfBot Liczba botow.
   * @param maxPlayers Maksymalna liczba graczy.
   * @param ifPlayerHost Czy gracz jest hostem.
   * @param ifHostPlay Czy host gra.
   * @param client Referencja do klasy glownej programu.
   */
  public GameController(int actualNumberOfPlayers, int numberOfBot, int maxPlayers, boolean ifPlayerHost, boolean ifHostPlay, Client client) {
	this.actualNumberOfPlayers=actualNumberOfPlayers;
	this.numberOfBot=numberOfBot;
	this.maxPlayers=maxPlayers;
	this.isPlayerHost=ifPlayerHost;
	this.isHostPlay=ifHostPlay;

	PlayersID = new String[maxPlayers];
    for(int i=0;i<PlayersID.length;i++)
      PlayersID[i]=Integer.toString(-1);

	ReplaceCards = new int[5];
    for(int i=0;i<ReplaceCards.length;i++)
      ReplaceCards[i]=0;

    PlayersDecks = new int[maxPlayers][2][5];
    for(int i=0;i<PlayersDecks.length;i++)
      for(int j=0;j<PlayersDecks[i][0].length;j++) {
        PlayersDecks[i][0][j]=0; 
	    PlayersDecks[i][1][j]=4;
	  }

    this.client=client;
  }
  /**
   * Odswierzanie listy dostepnych gier.
   */
  public void Refresh() {
    client.getGameWindow().ChangeWindow(PlayersDecks, maxPlayers, ReplaceCards);
  }
  /**
   * Klasa obslugujaca komunikat przesylany przez server. Podajaca talie gracza.
   * @param PlayerDeck Talicza gracza.
   */
  public void S_CARDS(int[][] PlayerDeck) {   
    client.getGameWindow().getStartGame().setVisible(false);
    client.getGameWindow().getChangeCards().setVisible(true);
    for(int i=0;i<PlayersDecks.length;i++)
      for(int j=0;j<PlayersDecks[i][0].length;j++) {
        PlayersDecks[i][0][j]=0; 
        PlayersDecks[i][1][j]=4;
      }
	this.PlayersDecks[0]=PlayerDeck;
	client.getGameWindow().getTimeAndWiner().setVisible(true);
	timer = new Timer();
	timerThread = new TimerThread(client.getGameWindow().getTimeAndWiner(), client);

	timer.schedule(timerThread, 0, 1000);

	client.getGameWindow().ChangeWindow(PlayersDecks, maxPlayers, ReplaceCards);
  }

  /**
   * Komunikat servera okreslajacy ID gracz.
   * @param PlayerID Id gracza.
   */
  public void S_ID(String PlayerID) {
    this.PlayersID[0]=PlayerID;
    if(!PlayerID.equals("0")) client.getGameWindow().getStartGame().setVisible(false);
    client.getGameWindow().ChangeWindow(PlayersDecks, actualNumberOfPlayers, ReplaceCards);
  }
  /**
   * Komunikat servera dolaczenia gracza do gry.
   * @param actualNumberOfPlayer aktualna liczba graczy.
   */
  public void G_PLAYERJOIN(int actualNumberOfPlayer) {
    this.actualNumberOfPlayers=actualNumberOfPlayer;
    client.getGameWindow().ChangeWindow(PlayersDecks, actualNumberOfPlayer, ReplaceCards);
  }
  /**
   * Komunikat servera opuszczenia przez gracz gry.
   * @param actualNumberOfPlayer
   */
  public void G_PLAYEROUT(int actualNumberOfPlayer) {
    this.actualNumberOfPlayers=actualNumberOfPlayer;
    client.getGameWindow().ChangeWindow(PlayersDecks, actualNumberOfPlayer, ReplaceCards);
  }
  /**
   * Komunikat gracza wysylajaca zaznaczone kart do wymiany.
   */
  public void G_WYMIANA() {
	if(timer!=null) timer.cancel();
    int numberOfChangedCards=0;
    for(int i=0; i<ReplaceCards.length; i++)
      if(ReplaceCards[i]>0)
    	numberOfChangedCards++;

    if(numberOfChangedCards>4)
      JOptionPane.showMessageDialog(null, "Zaduza liczba kart do wymiany");//blad
    else {
      int[] Cards = new int[numberOfChangedCards];
      int cardPosition=0;
      for(int i=0; i<ReplaceCards.length; i++)
        if(ReplaceCards[i]>0) {
          Cards[cardPosition]=i;
          cardPosition++;
        }
      client.getGameThread().getClientGTaskController().G_WYMIANA(Cards);
    }

  }
  /**
   * Komunikat serwera wysylajacy talie wszystkich graczy oraz id zwyciescy.
   * @param PlayersID Id graczy.
   * @param PlayersDecks Talie graczy.
   * @param idWiner Id zwyciescy.
   */
  public void G_ALL(String[] PlayersID, int[][][] PlayersDecks, String idWiner) {
    boolean ifNotExist;
    boolean[] freePosition = new boolean[this.maxPlayers];
    for(int i=0; i<this.maxPlayers; i++)
      freePosition[i]=true;
    
    System.out.println(this.PlayersID[0]+"  "+PlayersID[0]+"  "+idWiner);

	for(int i=0; i<this.maxPlayers; i++) {
	  ifNotExist=true;
      for(int j=0; j<this.maxPlayers; j++)
        if(this.PlayersID[i].equals(PlayersID[j])) {
          for(int k=0; k<5; k++) {
            this.PlayersDecks[i][0][k]=PlayersDecks[j][0][k];
            this.PlayersDecks[i][1][k]=PlayersDecks[j][1][k];
          }
          freePosition[j]=false;
          ifNotExist=false;
        }
	  if(ifNotExist && i!=0) {
	    for(int k=0; k<maxPlayers; k++)
	      if(freePosition[k]) {
	    	freePosition[k]=false;
	        this.PlayersID[i]=PlayersID[k];
	        for(int l=0; l<5; l++) {
	          this.PlayersDecks[i][0][l]=PlayersDecks[k][0][l];
	          this.PlayersDecks[i][1][l]=PlayersDecks[k][1][l];
	        }

	        k=maxPlayers;
	      }
	  }
	  else
		;//BLAD
	}


    for(int i=0; i<ReplaceCards.length; i++)
      ReplaceCards[i]=0;

    for(int i=0; i<maxPlayers; i++)
      if(this.PlayersID[i].startsWith("B"))
        client.getGameWindow().getIDPlayers()[i].setText("BOT "+this.PlayersID[i].substring(1));
      else
    	client.getGameWindow().getIDPlayers()[i].setText("PLAYER "+this.PlayersID[i]);
    
    client.getGameWindow().getChangeCards().setVisible(false);
    if(isPlayerHost) client.getGameWindow().getNextDeal().setVisible(true);
    if(idWiner.startsWith("B"))
      client.getGameWindow().getTimeAndWiner().setText("BOT "+idWiner.substring(1)+" WON");
    else if(idWiner.startsWith("Remis"))
      client.getGameWindow().getTimeAndWiner().setText(idWiner);
    else
      client.getGameWindow().getTimeAndWiner().setText("PLAYER "+idWiner+" WON");
	
	client.getGameWindow().ChangeWindow(this.PlayersDecks, maxPlayers, ReplaceCards);
  }
  /**
   * Specjalny komunikat dla gry w ktorej graja same boty.
   * @param PlayersID Id gracza.
   * @param PlayersDecks Talia graczy.
   */
  public void G_BALL(String[] PlayersID, int[][][] PlayersDecks) {
    boolean ifNotExist;
    boolean[] freePosition = new boolean[this.maxPlayers];
    for(int i=0; i<this.maxPlayers; i++)
      freePosition[i]=true;

	for(int i=0; i<this.maxPlayers; i++) {
	  ifNotExist=true;
      for(int j=0; j<this.maxPlayers; j++)
        if(this.PlayersID[i].equals(PlayersID[j])) {
          for(int k=0; k<5; k++) {
            this.PlayersDecks[i][0][k]=PlayersDecks[j][0][k];
            this.PlayersDecks[i][1][k]=PlayersDecks[j][1][k];
          }
          freePosition[j]=false;
          ifNotExist=false;
        }
	  if(ifNotExist) {
	    for(int k=0; k<maxPlayers; k++)
	      if(freePosition[k]) {
	    	freePosition[k]=false;
	        this.PlayersID[i]=PlayersID[k];
	        for(int l=0; l<5; l++) {
	          this.PlayersDecks[i][0][l]=PlayersDecks[k][0][l];
	          this.PlayersDecks[i][1][l]=PlayersDecks[k][1][l];
	        }

	        k=maxPlayers;
	      }
	  }
	  else
		;//BLAD
	}

    client.getGameWindow().getStartGame().setVisible(false);
    client.getGameWindow().getChangeCards().setVisible(true);
    client.getGameWindow().getTimeAndWiner().setVisible(true);
    client.getGameWindow().ChangeWindow(this.PlayersDecks, maxPlayers, ReplaceCards);
  }
  /**
   * Nowa rozgrywa pokera.
   */
  public void G_NEW() {
    client.getGameThread().getClientGTaskController().G_NEW();
    client.getGameWindow().getTimeAndWiner().setText("");

    if(isPlayerHost) client.getGameWindow().getNextDeal().setVisible(false);
  }
  /**
   * Maksymalna liczba graczy.
   * @return maksymalna liczbe graczy.
   */
  public int getMaxPlayers() {
    return maxPlayers;
  }
  /**
   * Pobranie tablicy kart do wymiany.
   * @return Tablica kart do wymiany.
   */
  public int[] getReplaceCards() {
    return ReplaceCards;
  }
  /**
   * Pobranie tali graczy.
   * @return Talia graczy.
   */
  public int[][][] getPlayersDecks() {
    return PlayersDecks;
  }
  /**
   * Pobranie id graczy.
   * @return Tablica ID graczy.
   */
  public String[] getPlayersID() {
    return PlayersID;
  }
  /**
   * Pobranie aktualnej liczby graczy.
   * @return Aktualna liczba graczy.
   */
  public int getActualNumberOfPlayers() {
    return actualNumberOfPlayers;
  }
  /**
   * Pobranie liczby botow.
   * @return Liczba botow w grze.
   */
  public int getNumberOfBot() {
    return numberOfBot;
  }
  /**
   * Sprawdzenie czy gracz jest hostem.
   * @return Czy gracz jest hostem.
   */
  public boolean isPlayerHost() {
    return isPlayerHost;
  }
  /**
   * Sprawdzenie czy host gra.
   * @return Czy host gra.
   */
  public boolean isHostPlay() {
    return isHostPlay;
  }
  /**
   * Edycja kart ktore chcemy wymienic.
   * @param ReplaceCards Nowa wersja kart ktore chemy wymienic.
   */
  public void setReplaceCards(int[] ReplaceCards) {
    this.ReplaceCards=ReplaceCards;
  }
  /**
   * Edycja id graczy.
   * @param PlayersID Tablica id graczy.
   */
  public void setPlayersID(String[] PlayersID) {
    this.PlayersID = PlayersID;
  }
}
